import * as Cesium from '@cesiumjs';
import {
  g3x_defineProperty,
  g3x_defineReadonly
} from "@g3x/utils";
import {
  autorun,
  reaction,
  intercept,
  observable,
  extendObservable,
  computed
} from 'mobx';
// import {
//   defineComponent,
//   ref,
//   reactive,
//   watch,
//   toRaw
// } from 'vue';

function CesiumDrawing(viewer) {

  const _this = this;

  g3x_defineReadonly(_this, "viewer", viewer);
  g3x_defineReadonly(_this, "scene", viewer.scene);
  g3x_defineReadonly(_this, "canvas", viewer.canvas);

  _this.floatingPoint = undefined;
  _this.activeShape = undefined;
  _this.activeShapePoints = [];

  const viewModel =  observable({
    drawingMode: 'line'
  });
  Object.defineProperty(_this, "drawingMode", {
    get() {
      return viewModel.drawingMode
    },
    set(val) {
      viewModel.drawingMode = val
    }
  })
  reaction(() => {
    return _this.drawingMode
  }, () => {
    terminateShape()
  })

  //绘制图形
  //初始化为线
  function drawShape(positionData) {
    const {
      viewer,
      drawingMode,
      floatingPoint,
      activeShape,
      activeShapePoints
    } = _this;
    var shape;
    if (drawingMode === 'line') {
      shape = viewer.entities.add({
        polyline: {
          positions: positionData,
          // clampToGround: true,
          depthTest: false,
          width: 3
        }
      });
    } else if (drawingMode === 'polygon') {
      shape = viewer.entities.add({
        polygon: {
          hierarchy: positionData,
          material: new Cesium.ColorMaterialProperty(Cesium.Color.WHITE.withAlpha(0.7))
        }
      });
    } else if (drawingMode === 'circle') {
      //当positionData为数组时绘制最终图，如果为function则绘制动态图
      var value = typeof positionData.getValue === 'function' ? positionData.getValue(0) : positionData;
      //var start = activeShapePoints[0];
      //var end = activeShapePoints[activeShapePoints.length - 1];
      //var r = Math.sqrt(Math.pow(start.x - end.x, 2) + Math.pow(start.y - end.y, 2));
      //r = r ? r : r + 1;
      shape = viewer.entities.add({
        position: activeShapePoints[0],
        name: 'Blue translucent, rotated, and extruded ellipse with outline',
        type: 'Selection tool',
        ellipse: {
          semiMinorAxis: new Cesium.CallbackProperty(function() {
            //半径 两点间距离
            var r = Math.sqrt(Math.pow(value[0].x - value[value.length - 1].x, 2) + Math.pow(value[0].y -
              value[value.length - 1].y, 2));
            return r ? r : r + 1;
          }, false),
          semiMajorAxis: new Cesium.CallbackProperty(function() {
            var r = Math.sqrt(Math.pow(value[0].x - value[value.length - 1].x, 2) + Math.pow(value[0].y -
              value[value.length - 1].y, 2));
            return r ? r : r + 1;
          }, false),
          material: Cesium.Color.BLUE.withAlpha(0.5),
          outline: true
        }
      });
    } else if (drawingMode === 'rectangle') {
      //当positionData为数组时绘制最终图，如果为function则绘制动态图
      var arr = typeof positionData.getValue === 'function' ? positionData.getValue(0) : positionData;
      shape = viewer.entities.add({
        name: 'Blue translucent, rotated, and extruded ellipse with outline',
        rectangle: {
          coordinates: new Cesium.CallbackProperty(function() {
            var obj = Cesium.Rectangle.fromCartesianArray(arr);
            //if(obj.west==obj.east){ obj.east+=0.000001};
            //if(obj.south==obj.north){obj.north+=0.000001};
            return obj;
          }, false),
          material: Cesium.Color.RED.withAlpha(0.5)
        }
      });
    }
    return shape;
  }

  function onMouseClick(event) {
    const {
      viewer,
      drawingMode,
      activeShape,
      activeShapePoints
    } = _this;

    //绘制点
    function createPoint(worldPosition) {
      // worldPosition.z += 500;
      var point = viewer.entities.add({
        position: worldPosition,
        point: {
          color: Cesium.Color.WHITE,
          pixelSize: 5,
          // heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
        }
      });
      return point;
    }

    // We use `viewer.scene.pickPosition` here instead of `viewer.camera.pickEllipsoid` so that
    // we get the correct point when mousing over terrain.
    var earthPosition = viewer.scene.pickPosition(event.position);
    // `earthPosition` will be undefined if our mouse is not over the globe.
    if (Cesium.defined(earthPosition)) {
      if (activeShapePoints.length === 0) {
        _this.floatingPoint = createPoint(earthPosition);
        activeShapePoints.push(earthPosition);
        var dynamicPositions = new Cesium.CallbackProperty(function() {
          if (drawingMode === 'polygon') {
            return new Cesium.PolygonHierarchy(activeShapePoints);
          }
          return activeShapePoints;
        }, false);
        _this.activeShape = drawShape(dynamicPositions); //绘制动态图
      }
      activeShapePoints.push(earthPosition);
      // createPoint(earthPosition);
    }
  }

  function onMouseMove(event) {
    const {
      scene,
      floatingPoint,
      activeShapePoints
    } = _this;
    var newPosition = scene.pickPosition(event.endPosition);
    if (Cesium.defined(floatingPoint)) {
      if (Cesium.defined(newPosition)) {
        floatingPoint.position.setValue(newPosition);
        activeShapePoints.pop();
        activeShapePoints.push(newPosition);
      }
    }
  }

  function onMouseDoubleClick(event) {}

  function terminateShape() {
    const {
      viewer,
      floatingPoint,
      activeShape,
      activeShapePoints
    } = _this;

    activeShapePoints.pop(); //去除最后一个动态点
    if (activeShapePoints.length) {
      drawShape(activeShapePoints); //绘制最终图
    }
    viewer.entities.remove(floatingPoint); //去除动态点图形（当前鼠标点）
    viewer.entities.remove(activeShape); //去除动态图形
    _this.floatingPoint = undefined;
    _this.activeShape = undefined;
    _this.activeShapePoints = [];
  }

  _this.destroy = function() {}

  function initEvents() {
    const {
      viewer,
      scene,
      canvas
    } = _this;
    viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType
      .LEFT_DOUBLE_CLICK);
    g3x_defineReadonly(_this, "eventHandler", new Cesium.ScreenSpaceEventHandler(canvas));
    _this.eventHandler.setInputAction(onMouseClick, Cesium.ScreenSpaceEventType.LEFT_CLICK);
    _this.eventHandler.setInputAction(onMouseDoubleClick, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
    _this.eventHandler.setInputAction(onMouseMove, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
    _this.eventHandler.setInputAction(terminateShape, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
  }

  initEvents();

  return _this;
}

export default CesiumDrawing;
